﻿// -----------------------------------------------------------------------
//  <copyright file="StoreService.Shipment.cs" company="柳柳软件">
//      Copyright (c) 2014-2015 66SOFT. All rights reserved.
//  </copyright>
//  <site>http://www.66soft.net</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2015-12-07 18:02</last-date>
// -----------------------------------------------------------------------

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

using OSharp.Core.Mapping;
using OSharp.Utility;
using OSharp.Utility.Data;

using ZH.JY.Store.Dtos;
using ZH.JY.Store.Models;


namespace ZH.JY.Store
{
    partial class StoreService
    {
        #region Implementation of IStoreContract

        /// <summary>
        /// 获取 出货记录信息查询数据集
        /// </summary>
        public IQueryable<Shipment> Shipments
        {
            get { return ShipmentRepository.Entities; }
        }

        /// <summary>
        /// 检查出货记录信息信息是否存在
        /// </summary>
        /// <param name="predicate">检查谓语表达式</param>
        /// <param name="id">更新的出货记录信息编号</param>
        /// <returns>出货记录信息是否存在</returns>
        public Task<bool> CheckShipmentExists(Expression<Func<Shipment, bool>> predicate, int id = 0)
        {
            predicate.CheckNotNull("predicate");
            return ShipmentRepository.CheckExistsAsync(predicate, id);
        }

        /// <summary>
        /// 添加出货记录信息信息
        /// </summary>
        /// <param name="dtos">要添加的出货记录信息DTO信息</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> CreateShipments(params ShipmentInputDto[] dtos)
        {
            dtos.CheckNotNull("dtos");
            if (dtos.Length == 0)
            {
                return new OperationResult(OperationResultType.Error, "无法一次新增多个出货信息");
            }
            ShipmentInputDto dto = dtos[0];
            if (dto.Count <= 0)
            {
                return new OperationResult(OperationResultType.Error, "产品出货数量必须大于0");
            }
            ShipmentRepository.UnitOfWork.TransactionEnabled = true;
            Shipment shipment = dto.MapTo<Shipment>();
            Customer customer = await CustomerRepository.GetByKeyAsync(dto.CustomerId);
            if (customer == null)
            {
                return new OperationResult(OperationResultType.Error, "指定编号的客户信息不存在");
            }
            shipment.Customer = customer;
            Product product = await ProductRepository.GetByKeyAsync(dto.ProductId);
            if (product == null)
            {
                return new OperationResult(OperationResultType.Error, "指定编号的商品信息不存在");
            }
            if (product.Count <= 0)
            {
                return new OperationResult(OperationResultType.Error, $"商品“{product.Name}”库存不足，当前为{product.Count}个，实际需要{shipment.Count}个");
            }
            if (product.Count < shipment.Count)
            {
                return new OperationResult(OperationResultType.Error, $"商品“{product.Name}”的库存不足，当前数量为{product.Count}个，实际需要{shipment.Count}个");
            }
            product.Count -= shipment.Count;
            shipment.Product = product;
            await ShipmentRepository.InsertAsync(shipment);
            await ProductRepository.UpdateAsync(product);

            return await ShipmentRepository.UnitOfWork.SaveChangesAsync() > 0
                ? new OperationResult(OperationResultType.Success, $"客户“{customer.Name}”的 {shipment.Count} 个商品“{product.Name}”出货成功，当前库存总数为 {product.Count}")
                : OperationResult.NoChanged;
        }

        /// <summary>
        /// 更新出货记录信息信息
        /// </summary>
        /// <param name="dtos">包含更新信息的出货记录信息DTO信息</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> UpdateShipments(params ShipmentInputDto[] dtos)
        {
            dtos.CheckNotNull("dtos");
            if (dtos.Length == 0)
            {
                return new OperationResult(OperationResultType.Error, "无法一次更改多个出货信息");
            }
            ShipmentInputDto dto = dtos[0];
            if (dto.Count <= 0)
            {
                return new OperationResult(OperationResultType.Error, "产品出货数量必须大于0");
            }
            ShipmentRepository.UnitOfWork.TransactionEnabled = true;
            Shipment shipment = await ShipmentRepository.GetByKeyAsync(dto.Id);
            if (shipment.Customer.Id != dto.CustomerId)
            {
                Customer customer = await CustomerRepository.GetByKeyAsync(dto.CustomerId);
                if (customer == null)
                {
                    return new OperationResult(OperationResultType.Error, "指定编号的客户信息不存在");
                }
                shipment.Customer = customer;
            }
            if (shipment.Product.Id == dto.ProductId)
            {
                int count = dto.Count - shipment.Count;
                if (count > 0 && shipment.Product.Count < count)
                {
                    return new OperationResult(OperationResultType.Error,
                        $"产品“{shipment.Product.Name}”库存数量不足，当前库存为{shipment.Product.Count}，需求库存为{count}");
                }
                shipment.Count = dto.Count;
                shipment.Product.Count -= count;
                await ShipmentRepository.UpdateAsync(shipment);
                await ProductRepository.UpdateAsync(shipment.Product);
            }
            else
            {
                Product oldProduct = shipment.Product;
                oldProduct.Count += shipment.Count;
                Product newProduct = await ProductRepository.GetByKeyAsync(dto.ProductId);
                if (newProduct.Count < dto.Count)
                {
                    return new OperationResult(OperationResultType.Error,
                        $"产品“{oldProduct.Name}”库存数量不足，当前库存为{newProduct.Count}，需求库存为{dto.Count}");
                }
                newProduct.Count -= dto.Count;
                shipment.Product = newProduct;
                await ShipmentRepository.UpdateAsync(shipment);
                await ProductRepository.UpdateAsync(oldProduct);
                await ProductRepository.UpdateAsync(newProduct);
            }
            return await ShipmentRepository.UnitOfWork.SaveChangesAsync() > 0
                ? new OperationResult(OperationResultType.Success, "商品出货信息更新成功")
                : OperationResult.NoChanged;
        }

        /// <summary>
        /// 删除出货记录信息信息
        /// </summary>
        /// <param name="ids">要删除的出货记录信息编号</param>
        /// <returns>业务操作结果</returns>
        public async Task<OperationResult> DeleteShipments(params int[] ids)
        {
            ids.CheckNotNull("ids");
            if (ids.Length != 1)
            {
                return new OperationResult(OperationResultType.Error, "无法删除多个出货信息");
            }
            int id = ids[0];
            ShipmentRepository.UnitOfWork.TransactionEnabled = true;
            Shipment shipment = await ShipmentRepository.GetByKeyAsync(id);
            Product product = shipment.Product;
            product.Count += shipment.Count;
            await ShipmentRepository.DeleteAsync(shipment);
            await ProductRepository.UpdateAsync(product);
            return await ShipmentRepository.UnitOfWork.SaveChangesAsync() > 0
                ? new OperationResult(OperationResultType.Success, $"{shipment.Count} 个商品“{product.Name}”出货信息删除成功，当前库存总数为：{product.Count}")
                : OperationResult.NoChanged;
        }

        #endregion
    }
}